// 绘制文字的方法
export const drawFontCtx = async (ctx: any, fontForm: any) => {
  ctx.font = `${fontForm.fontStyle} ${fontForm.fontWeight} ${fontForm.fontSize}px ${fontForm.fontFamily}`
  await drawFillStyle(ctx, fontForm.fillStyle)
  await drawShadow(ctx, fontForm.shadow)
}

export async function drawShapes(ctx: any, shape: any) {
  if (shape.type == 'Rect') {
    drawRect(ctx, shape)
    if (shape.fillStyle?.fillType == 'fill') {
      ctx.fillStyle = await drawFillStyle(ctx, shape.fillStyle)
      ctx.fill()
    }
    if (shape.strokeStyle?.fillType == 'fill') {
      ctx.strokeStyle = await drawFillStyle(ctx, shape.strokeStyle)
      ctx.stroke()
    }
  }
}
/**
 * 剪切图形
 */
function cilpShapes(ctx: any, shape: any) {
  return new Promise((resolve, reject) => {
    drawRect(ctx, shape)
    ctx.clip()
  }).then(() => {})
}
function drawRect(ctx: any, rectForm: any) {
  let x = rectForm.x,
    y = rectForm.y,
    w = rectForm.width,
    h = rectForm.height,
    ltr = rectForm.cornerRadius[0] || 0,
    rtr = rectForm.cornerRadius[1] || 0,
    rbr = rectForm.cornerRadius[2] || 0,
    lbr = rectForm.cornerRadius[3] || 0

  ctx.beginPath()
  ctx.moveTo(x, y + ltr)
  ltr && ctx.arcTo(x, y, x + ltr, y, ltr)
  ctx.lineTo(x + w - rtr, y)
  rtr && ctx.arcTo(x + w, y, x + w, y + rtr, rtr)
  ctx.lineTo(x + w, y + h - rbr)
  rbr && ctx.arcTo(x + w, y + h, x + w - rbr, y + h, rbr)
  ctx.lineTo(x + lbr, y + h)
  lbr && ctx.arcTo(x, y + h, x, y + h - lbr, lbr)
  ctx.closePath()
}
// 绘制图片或者视频的方法
export async function drawImgCtx(ctx: any, imgForm: any) {
  drawShadow(ctx, imgForm.shadow)
  let img = await getImage(imgForm.imgUrl)
  if (imgForm.swidth) {
    ctx.drawImage(
      img,
      imgForm.sx,
      imgForm.sy,
      imgForm.swidth,
      imgForm.sheight,
      imgForm.x,
      imgForm.y,
      imgForm.width,
      imgForm.height
    )
  } else {
    ctx.drawImage(img, imgForm.x, imgForm.y, imgForm.width, imgForm.height)
  }
}
// 填充样式 渐变 和背景的方法
const drawFillStyle = async (ctx: any, fillStyle: any) => {
  let style: any
  if (fillStyle.type === 'fillColor') {
    style = fillStyle[fillStyle.type]
  }
  if (fillStyle.type === 'fillGradualColor') {
    // 环形渐变
    if (fillStyle.fillGradualShape.r0 && fillStyle.fillGradualShape.r1) {
      style = ctx.createRadialGradient(
        fillStyle.fillGradualShape.x0,
        fillStyle.fillGradualShape.y0,
        fillStyle.fillGradualShape.r0,
        fillStyle.fillGradualShape.x1,
        fillStyle.fillGradualShape.y1,
        fillStyle.fillGradualShape.r1
      )
      // 线形渐变
    } else {
      style = ctx.createLinearGradient(
        fillStyle.fillGradualShape.x0,
        fillStyle.fillGradualShape.y0,
        fillStyle.fillGradualShape.x1,
        fillStyle.fillGradualShape.y1
      )
    }

    fillStyle.fillGradualColor.forEach((item: any) => {
      style.addColorStop(item.step * 0.01, item.color)
    })
  }
  if (fillStyle.type === 'fillImg') {
    let img = await getImage(fillStyle.fillImg.url)
    style = ctx.createPattern(img, fillStyle.fillImg.repeat)
  }
  return style
}
// 设置实例对象阴影的相关配置
const drawShadow = (ctx: any, shadow: any) => {
  ctx.shadowOffsetX = shadow.shadowOffsetX
  ctx.shadowOffsetY = shadow.shadowOffsetY
  ctx.shadowBlur = shadow.shadowBlur
  ctx.shadowColor = shadow.shadowColor
}

// 处理文字换行以及最后的绘制
const textLineFeed = (
  ctx: any,
  type: string,
  t: string,
  x: number,
  y: number,
  s: number,
  w: number,
  id: string
) => {
  //参数说明
  //ctx：canvas的 2d 对象，t：绘制的文字，x,y:文字坐标，s 文字的大小/行高,w：文字最大宽度
  let chr = t.split('') // 把当前文字转化为数组
  let temp = '' // 当前用来做比较的字符串
  let row = [] // 最后分完行的文字数组

  for (let a = 0; a < chr.length; a++) {
    if (
      ctx.measureText(temp).width < w &&
      ctx.measureText(temp + chr[a]).width <= w
    ) {
      temp += chr[a]
    } else {
      row.push(temp)
      temp = chr[a]
    }
  }
  row.push(temp)
  for (let b = 0; b < row.length; b++) {
    if (type == 'fill') {
      ctx.fillText(row[b], x, y + (b + 1) * s) //每行字体y坐标间隔
    } else {
      ctx.strokeText(row[b], x, y + (b + 1) * s)
    }
  }
}

// 获取图片完成加载后的实例对象
export const getImage = (imgSrc: string) => {
  return new Promise((resolve, reject) => {
    let img = new Image()
    img.src = imgSrc
    img.crossOrigin = 'anonymous'
    img.onload = function () {
      resolve(img)
    }
  })
}
